var stream = require('stream')
var url = require('url')
var util = require('util')

var syrup = require('stf-syrup')
var request = require('request')
var Promise = require('bluebird')

var logger = require('../../../util/logger')
var wire = require('../../../wire')
var wireutil = require('../../../wire/util')
var promiseutil = require('../../../util/promiseutil')


module.exports = syrup.serial()
  .dependency(require('../support/adb'))
  .dependency(require('../support/router'))
  .dependency(require('../support/push'))
  .define(function(options, adb, router, push) {
    var log = logger.createLogger('device:plugins:displayImage')
    router.on(wire.DisplayImageMessage, function(channel, message) {

      log.info('displayImage from "%s"', message.href)

      var reply = wireutil.reply(options.serial)
      var target = '/sdcard/Pictures/Screenshots/image.'+message.href.substr(message.href.indexOf(".")+1)

      function sendProgress(data, progress) {
        push.send([
          channel
        , reply.progress(data, progress)
        ])
      }

      function displayImage() {
        var req = request({
          url: url.resolve(options.storageUrl, message.href)
        })

        // We need to catch the Content-Length on the fly or we risk
        // losing some of the initial chunks.
        var contentLength = null
        req.on('response', function(res) {
          contentLength = parseInt(res.headers['content-length'], 10)
        })

        var source = new stream.Readable().wrap(req)

        return adb.push(options.serial, source, target)
          .timeout(10000)
          .then(function(transfer) {
            var resolver = Promise.defer()

            function progressListener(stats) {
              if (contentLength) {
                // Progress 0% to 70%
                sendProgress(
                  'pushing_image'
                , 50 * Math.max(0, Math.min(
                    50
                  , stats.bytesTransferred / contentLength
                  ))
                )
              }
            }

            function errorListener(err) {
              resolver.reject(err)
            }

            function endListener() {
              resolver.resolve(target)
            }

            transfer.on('progress', progressListener)
            transfer.on('error', errorListener)
            transfer.on('end', endListener)

            return resolver.promise.finally(function() {
              transfer.removeListener('progress', progressListener)
              transfer.removeListener('error', errorListener)
              transfer.removeListener('end', endListener)
            })
          })
      }

      // Progress 0%
      sendProgress('pushing_image', 0)
      displayImage()
        .then(function() {
          var command ='am start -t image/* -a android.intent.action.VIEW -d file://'+target;
          return adb.shell(options.serial,command)
        })
        .then(function() {
          push.send([
            channel
          , reply.okay('DISPLAY_SUCCEEDED')
          ])
        })
        .catch(Promise.TimeoutError, function(err) {
          log.error('Display image failed', err.stack)
          push.send([
            channel
          , reply.fail('DIAPLAY_ERROR_TIMEOUT')
          ])
        })
        .catch(function(err) {
          log.error('Display image failed', err.stack)
          push.send([
            channel
          , reply.fail('DIAPLAY_ERROR_UNKNOWN')
          ])
        })
    })
  })
